/** Mobile skill base class.
 *
 * A mobile skill typically casts a spell and consumes magic points, although
 * any range of other things are possible.
 */
function Skill()
{
	this.name = "Skill";
	this.spell = null;
	this.cost = 1;
}
Skill.prototype = { };
/** Create a new skill by its ID.
 *@param id The ID of the item.
 */
Skill.newById = function(id)
{
	var ret = new Skill();
	ret.init.call(ret, skills[id]);
	ret.__baseId = id;
	return ret;
}
/** Initialization routine for skill properties.
 *
 * All members of bag may be an array of possbile values.
 *@param name The name of the skill.
 *@param cost The mp cost of the skill. Skills may overload the pay() method to do something different with cost.
 *@param spell The spell that can be cast by using this skill.
 *@param spellParam A parameter bag for the spell effect. Not all spells use this, and skills may overload the getSpell() method to modify the parameters before they are sent to the spell generator.
 */
Skill.prototype.init = function(bag)
{
	util.mix(this, bag);
}
/** Use a skill.
 *@param source The source using the skill.
 *@param target The target of the skill.
 */
Skill.prototype.use = function(source, target)
{
	if(!this.pay(source, true, true))
		return;
	var spell = this.getSpell();
	spell.apply(source, target);
	if(source.isMobile)
		source.statCheck();
	if(target.isMobile)
	{
		target.wasHitBy(source);
		target.statCheck();
	}
}
/** Tells us if we can use this skill.
 *@param source The mobile trying to use the item.
 *@param doMessage If true we will print a message saying why we can't use the item.
 */
Skill.prototype.canUse = function(source, doMessage)
{
	return this.pay(source, false, doMessage)
}
Skill.prototype.getSpell = function()
{
	return Spell.newById(this.spell, this.spellParam);
}
/** Pays for a skill invokation.
 *@param source The mobile trying to use the skill.
 *@param forReal If this is true that the payment should actually be deducted.
 *@param doMessage If true we will print a message saying why we can't use the skill.
 *@return True if payment was successful (or possible), false otherwise.
 */
Skill.prototype.pay = function(source, forReal, doMessage)
{
	if(source.mp < this.cost)
	{
		if(doMessage)
			dhack.logWindow.pushMessage("%b0Not enough magic points.%f0");
		return false;
	}
	if(forReal)
		source.mp -= this.cost;
	return true;
}
/** Returns a string describing what the skill costs to use.
 *@param source The mobile trying to use the skill.
 */
Skill.prototype.costString = function()
{
	return "MP " + this.cost;
}
Skill.prototype.getUsableEffectsString = function(source)
{
	var spell = this.getSpell();
	var e = spell.getEffects(source);
	var totalMods = {};
	for(var i = 0; i < e.length; ++i)
	{
		util.addMix(totalMods, e[i].mods);
	}
	var ret = Mobile.getModEffectString(totalMods);
	return ret;
}
/** Re-links handler methods from the base definition.
 */
Spell.prototype.fromRON = function()
{
	var def = skills[this.__baseId];
	for(var o in def)
	{
		if(def.hasOwnProperty(o) &&
			typeof(def[o]) === "function")
			this[o] = def[o];
	}
}
ron.registerCtor(Skill, "Skill");
